<?php

use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
use think\facade\Db;
use think\migration\Migrator;

class GeoAtlas extends Migrator
{
    /**
     * Change Method.
     *
     * Write your reversible migrations using this method.
     *
     * More information on writing migrations is available here:
     * http://docs.phinx.org/en/latest/migrations.html#the-abstractmigration-class
     *
     * The following commands can be used in this method and Phinx will
     * automatically reverse them when rolling back:
     *
     *    createTable
     *    renameTable
     *    addColumn
     *    renameColumn
     *    addIndex
     *    addForeignKey
     *
     * Remember to call "create()" or "update()" and NOT "save()" when working
     * with the Table class.
     *
     * @throws GuzzleException
     */
    public function change(): void
    {

        $this->_createGeoAtlas();
        $this->_importGeoAtlas();
    }


    /**
     * 创建中国地图数据
     *
     * @return void
     */
    private function _createGeoAtlas(): void
    {
        $table = $this->table('geo_atlas', ['comment' => '中国地图数据']);
        $table->addColumn('name', 'string', ['limit' => 32, 'default' => '', 'comment' => '名称'])
              ->addColumn('adcode', 'string', ['limit' => 32, 'default' => '', 'comment' => '编码'])
              ->addColumn('level', 'string', ['limit' => 32, 'default' => '', 'comment' => '级别'])
              ->addColumn('parent', 'string', ['limit' => 32, 'default' => '', 'comment' => '父级编码'])
              ->addColumn('lng', 'string', ['limit' => 32, 'default' => '', 'comment' => '经度'])
              ->addColumn('lat', 'string', ['limit' => 32, 'default' => '', 'comment' => '纬度'])
              ->create();
    }

    /**
     * 导入地图数据
     *
     * @return void
     * @throws GuzzleException
     */
    private function _importGeoAtlas(): void
    {
        $Options          = ['base_uri' => 'https://datavmap-public.oss-cn-hangzhou.aliyuncs.com'];
        $httpClient       = new Client($Options);
        $responseProvince = $httpClient->request('GET', '/areas/csv/100000_province.json');
        $dataProvince     = json_decode($responseProvince->getBody()->getContents(), true);
        $resultCount      = Db::name('geo_atlas')->count();
        if ($resultCount >= 3000) {
            return;
        }
        // 插入省份数据
        Db::name('geo_atlas')->insertAll($this->removeColumn($dataProvince['rows'], 'people_count_2010'));
        foreach ($dataProvince['rows'] as $province) {
            $responseCity = $httpClient->request('GET', '/areas/csv/' . $province['adcode'] . '_city.json');
            $dataCity     = json_decode($responseCity->getBody()->getContents(), true);
            // 插入城市数据
            Db::name('geo_atlas')->insertAll($this->removeColumn($dataCity['rows'], 'people_count_2010'));

            $responseDistrict = $httpClient->request('GET', '/areas/csv/' . $province['adcode'] . '_district.json');
            $dataDistrict     = json_decode($responseDistrict->getBody()->getContents(), true);
            // 插入区县数据
            Db::name('geo_atlas')->insertAll($this->removeColumn($dataDistrict['rows'], 'people_count_2010'));
        }
    }


    /**
     * 使用array_map函数删除二维数组中指定列
     *
     * @param array  $array  要处理的数组
     * @param string $column 要删除的列名
     *
     * @return array
     */
    private function removeColumn(array $array, string $column): array
    {
        return array_map(function ($item) use ($column) {
            unset($item[$column]);
            return $item;
        }, $array);
    }

}
